﻿using System;
using Microsoft.Practices.Composite.Presentation.Events;
using Might.Infrastructure.DOM;
using Might.Infrastructure.Events;
using Might.Infrastructure.Services;

namespace Might.Core.DOM {

    public class UserInfo : DomNode , IUserInfo {            
        
        public UserInfo() {
            IsContainer = true;
            InsertChild( GroupNames.FileSystemRoot , new LocalFileSystemRoot() );
        }
       
        public string Name { get; set; }

        public string PassHash { get; set; }                  

    }

    public class SvnFileSystemRoot : DomNode , ISvnFileSystemRoot {
       
        //TODO : SVN by nemel delat po kazdem SAVE commit !!! (save bez commitu)

        private string name;
        private string uri;
        private string username;
        private string password;

        public event EndProgressEventHandler LoadListFinished;   

        public SvnFileSystemRoot() {
            IsContainer = true;
            CoreServices.EventAggregator.GetEvent<ProgressEvent>().Subscribe( ProgressEventsHandler , ThreadOption.UIThread , false );
        }              

        public string Name { 
            get { return name; }
            set { 
                name = value;
                OnChanged( this , "Name" );
            }            
        }

        public string Uri {
            get { return uri; }
            set {
                uri = value;
                OnChanged( this , "Uri" );
            }
        }

        public string Username {
            get { return username; }
            set {
                username = value;
                OnChanged(this, "Username");
            }
        }

        public string Password {
            get { return password; }
            set {
                password = value;
                OnChanged(this, "Password");
            }
        }

        public void LoadList() {
            CoreServices.EventAggregator.GetEvent<OpenFileSystemRootEvent>().Publish( this );
        }

        public void LoadList( IFile from ) {
            CoreServices.EventAggregator.GetEvent<OpenFileEvent>().Publish( from );
        }

        public void CheckIn() {
            throw new NotImplementedException();
        }

        public void CheckOut() {
            throw new NotImplementedException();
        }
       
        protected virtual void OnLoadListFinished( IProgressToken progressToken ) {            
            if( LoadListFinished != null ) {
                LoadListFinished( progressToken , progressToken.State as EndProgressEventArgs );
            }
        }

        public void ProgressEventsHandler( IProgressToken progressToken ) {
            if( progressToken.EventType == typeof( OpenFileEvent ) || progressToken.EventType == typeof( OpenFileSystemRootEvent ) ) {
                if( progressToken.State is EndProgressEventArgs ) {
                    OnLoadListFinished( progressToken );
                } else {
                    progressToken.ProgressGo += progressToken_ProgressGo;
                }
            }
        }

        private void progressToken_ProgressGo( IProgressToken sender , ProgressEventArgs e ) {
            if( sender.EventType == typeof( OpenFileEvent ) || sender.EventType == typeof( OpenFileSystemRootEvent ) ) {
                if( sender.State is EndProgressEventArgs ) {
                    sender.ProgressGo -= progressToken_ProgressGo;
                    OnLoadListFinished( sender );
                }
            }
        }  
        
    } 
    
    public class LocalFileSystemRoot : DomNode , ILocalFileSystemRoot {

        public event EndProgressEventHandler LoadListFinished;
        
        public LocalFileSystemRoot() {
            IsContainer = true;
            CoreServices.EventAggregator.GetEvent<ProgressEvent>().Subscribe( ProgressEventsHandler , ThreadOption.UIThread , false );
        }

        public string Name {
            get { return "Local file system"; }
            set {}
        }

        public string Uri {
            get { return ""; }                
            set {}
        }

        public void LoadList() {
            CoreServices.EventAggregator.GetEvent<OpenFileSystemRootEvent>().Publish( this );
        }

        public void LoadList( IFile from ) {
            LoadList();
        }

        protected virtual void OnLoadListFinished( IProgressToken progressToken ) {
            if( LoadListFinished != null ) {
                LoadListFinished( progressToken , progressToken.State as EndProgressEventArgs );
            }
        }

        public void ProgressEventsHandler( IProgressToken progressToken ) {
            if( progressToken.EventType == typeof( OpenFileEvent ) || progressToken.EventType == typeof( OpenFileSystemRootEvent ) ) {
                if( progressToken.State is EndProgressEventArgs ) {
                    OnLoadListFinished( progressToken );
                } else {
                    progressToken.ProgressGo += progressToken_ProgressGo;
                }
            }
        }

        private void progressToken_ProgressGo( IProgressToken sender , ProgressEventArgs e ) {
            if( sender.EventType == typeof( OpenFileEvent ) || sender.EventType == typeof( OpenFileSystemRootEvent ) ) {
                if( sender.State is EndProgressEventArgs ) {
                    sender.ProgressGo -= progressToken_ProgressGo;
                    OnLoadListFinished( sender );
                }
            }
        }

    }
 
    public class File : DomNode , IFile {

        private string name;       
        private string uri;
        private bool isDir;
        private System.IO.MemoryStream data;    
        
        public string Name {
             get { return name; }
             internal set {
                name = value;
                OnChanged( this , "Name" );
             }             
        }
        
        public string Uri {
             get { return uri; } 
             internal set { 
                uri = value;                                                
                OnChanged( this , "Uri" );
             }             
        }
        
        public bool IsDir { 
            get { return isDir; }
            protected set {
                isDir = value;
                IsContainer = value;
                OnChanged( this , "IsDir" );    
            }                
        }

        public System.IO.MemoryStream Data { 
            get { return data; } 
            internal set {
                data = value;
                OnChanged( this , "Data" );
                CoreServices.EventAggregator.GetEvent<FileDownloadedEvent>().Publish( this );
            }
        }

        public IFileSystemRoot FileSystem {
            get { return null; }
        }

        public void Move( IFile file ) {}
        public void Rename( string newName ) {}
        public void Save( IFile file ) {}
        public void Delete() {}

    }       
    
    public class LocalFile : File , ILocalFile {
               
        private System.IO.FileInfo fileInfo;
        private IFileSystemRoot fileSystem;
        
        public LocalFile() {
            IsDir = false;
            IsContainer = false;
        }

        public new IFileSystemRoot FileSystem {
            get { return fileSystem; }
            internal set {

                if( value is LocalFileSystemRoot ) {
                    fileSystem = value;
                    OnChanged( this , "FileSystem" );
                } else {
                    throw new ArgumentException( "SvnFile has to be inside ISvnFileSystem DomItem." );
                }

            }
        }

        public System.IO.FileInfo FileSystemInfo {
            get { return fileInfo; }
            set { fileInfo = value; }
        }        

        public new void Move( IFile file ) {
            throw new NotImplementedException();
        }

        public new void Rename( string newName ) {
            throw new NotImplementedException();
        }

        public new void Save( IFile file ) {
            throw new NotImplementedException();
        }

        public new void Delete() {
            throw new NotImplementedException();
        }
        
    }

    public class SvnFile : File , ISvnFile {

        private IFileSystemRoot fileSystem;

        public SvnFile( bool isDir ) {            
            IsDir = isDir;
            IsContainer = isDir;
        }                
        
        public new IFileSystemRoot FileSystem { 
            get { return fileSystem; }
            internal set {
                
                if( value is ISvnFileSystemRoot ) {
                    fileSystem = value;
                    OnChanged( this , "FileSystem" );
                } else {
                    throw new ArgumentException( "SvnFile has to be inside ISvnFileSystem DomItem." );
                }
                
            }
       }

        public new void Move(IFile file) {
            throw new NotImplementedException();
        }

        public new void Rename(string newName) {
            throw new NotImplementedException();
        }

        public new void Save(IFile file) {
            throw new NotImplementedException();
        }

        public new void Delete() {
            throw new NotImplementedException();
        }        

        #region ISvnFile Members

        public void CheckIn() {
            throw new NotImplementedException();
        }

        public void CheckOut() {
            throw new NotImplementedException();
        }

        #endregion
    }
}